package com.baidu.shoppingmall.auth.visitor;



import com.baidu.shoppingmall.auth.dao.AuthorityDAO;
import com.baidu.shoppingmall.auth.domain.AuthorityPO;
import com.baidu.shoppingmall.auth.composite.AuthorityNode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 在删除时查看用户名是否被占用
 */
@Repository
@SuppressWarnings("all")
public class CheckRoleAuthorityRelationVisitor implements AuthorityVisitor {
    @Autowired
    private AuthorityDAO authorityDAO;
    //false表示没有被占用

    //private Boolean status = false;

    //因为status属性设置为私有的，所以创建一个get方法便于获取该属性值

//    public Boolean getStatus() {
//        return status;
//    }

    public CheckRoleAuthorityRelationVisitor() {
    }
    @Override
    public void visit(AuthorityNode authorityNode) {
        //构造器，构造parent_id=parentId的条件查询条件
        QueryWrapper<AuthorityPO> queryWrapper=new QueryWrapper();
        Map<String, Object> map = new HashMap<>();
        map.put("parent_id", authorityNode.getId());
        queryWrapper.allEq(map);
        //根据权限的id查询子权限列表
        List<AuthorityPO> AuthorityPOs = authorityDAO.selectList(queryWrapper);
        //因为我们不想影响原来的AuthorityPO数据结构
        //所以我们现在把AuthorityPOs里面所有的数据克隆到AuthorityPOList
        List<AuthorityNode> AuthorityPOList = new ArrayList<>(AuthorityPOs.size());//新增许可 删除许可 修改许可

        //克隆AuthorityPOs集合里面的每个元素到AuthorityPOList集合里面
        AuthorityPOs.forEach(p -> {
            try {
                AuthorityPOList.add(p.clone(AuthorityNode.class));
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        //如果集合里面还有元素【许可维护==》新增许可 删除许可 修改许可】
        if (AuthorityPOList  != null && AuthorityPOList .size() > 0) {
            // 删除许可 修改许可  新增许可
            //this表示当前类  这里的this即是CheckRoleAuthorityRelationVisitor类
            /**
             * 怎么利用访问者模式  产生递归思想的：
             * 调用路线走向：这里是先调用的AuthorityNode类的accept方法，
             * 然后在AuthorityNode类中调用了AuthorityVisitor接口中的visit方法，
             * 即是调用AuthorityVisitor接口的实现类CheckRoleAuthorityRelationVisitor的方法visit
             * （为什么就直接能调用到CheckRoleAuthorityRelationVisitor的方法visit：因为AuthorityServiceImpl类中的delete方法调用了CheckRoleAuthorityRelationVisitor类的visit）
             *当一个树权限结构还是满足上面的if条件时，就会一直调用accept方法，
             * 当上述if条件不满足时，就会执行最底层的那个visit方法，当最底层一个visit方法执行完后，又执行倒数第二个visit方法，然后一直循环向上执行visit方法
             *
             *
             */

            AuthorityPOList .forEach(node -> node.accept(this));
        }
        boolean checkResult = checkRolePermissionRelation(authorityNode.getId());//新增许可的id

        if (checkResult) {
           // this.status = true;
            System.out.println(authorityNode.getAuthorityComment()+"=======》被使用");
            throw new RuntimeException(authorityNode.getAuthorityComment()+"被使用");
        }else{
            //this.status=false;
            System.out.println(authorityNode.getAuthorityComment()+"=========》未使用");
        }
    }

    /**
     *查看该权限是否被被使用
     * @param id
     * @return
     */
    private Boolean checkRolePermissionRelation(Long id) {//新增许可的id
        //查询是否被占用

        Integer count = authorityDAO.selectById(id).getPermissionUsage();//新增许可的id

        //如果存在就返回true

        if (count==1) {
            return true;
        }
        return false;
    }

}
